package com.frank.loadinglibrary.common.element;

import com.frank.loadinglibrary.base.baseanimations.BaseAnimationController;
import com.frank.loadinglibrary.base.baseelement.BaseElement;
import com.frank.loadinglibrary.base.baseelement.IComponentCallback;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;

import java.util.ArrayList;

/**
 * @author SUQI
 * @date 2021/6/4
 * @description 三个小球旋转
 **/
public class ChromeFloatingCirclesElement extends BaseElement implements BaseAnimationController.IAnimationController<AnimatorValue> {

    private final float valueZeroPointFive = 0.5f;
    private Paint mLeftTopPaint;
    private Paint mRightTopPaint;
    private Paint mLeftBottomPaint;
    private Paint mRightBottomPaint;

    float mOffset = 0;
    private ChromeFloatingCirclesParams params;

    public ChromeFloatingCirclesElement(ChromeFloatingCirclesParams params, IComponentCallback call) {
        super();
        this.params = params;
        this.callback = call;
    }

    @Override
    public void initPaint() {
        super.initPaint();

        Paint basePaint = new Paint();
        basePaint.setAntiAlias(true);
        basePaint.setStyle(Paint.Style.FILL_STYLE);
        basePaint.setStrokeWidth(2);

        if (mLeftTopPaint == null) {
            mLeftTopPaint = new Paint(basePaint);
        }
        mLeftTopPaint.setColor(params.colors[0]);

        if (mRightTopPaint == null) {
            mRightTopPaint = new Paint(basePaint);
        }
        mRightTopPaint.setColor(params.colors[1]);

        if (mLeftBottomPaint == null) {
            mLeftBottomPaint = new Paint(basePaint);
        }
        mLeftBottomPaint.setColor(params.colors[2]);

        if (mRightBottomPaint == null) {
            mRightBottomPaint = new Paint(basePaint);
        }
        mRightBottomPaint.setColor(params.colors[3]);
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        float width = getWidth();
        float height = getHeight();
        drawLeftTopCircle(width, height, canvas);
        drawLeftButtomCircle(width, height, canvas);
        drawRightButtomCircle(width, height, canvas);
        drawRightTopCircle(width, height, canvas);
    }

    @Override
    public ArrayList<AnimatorValue> onCreateAnimators() {
        ArrayList<AnimatorValue> animators = new ArrayList<AnimatorValue>();
        AnimatorValue animatorValue = new AnimatorValue();
        animatorValue.setDuration(params.durtion);
        animatorValue.setLoopedCount(-1);
        animators.add(animatorValue);
        animatorValue.setValueUpdateListener((animatorValue1, v) -> {
            mOffset = v;
            if (callback != null) {
                callback.reflushComponent();
            }
        });
        return animators;
    }

    @Override
    public void onAnimationReset() {
        //do nothing because donot need to reset animation params
    }

    @Override
    public BaseAnimationController.IAnimationController<AnimatorValue> initAnimationController() {
        return this;
    }

    private void drawLeftTopCircle(float width, float height, Canvas canvas) {
        float mLeftTopCenterX;
        float mLeftTopCenterY;
        if (mOffset <= valueZeroPointFive) {
            mLeftTopCenterX = (float) (width / 2 - params.mRectSpace / 2 + mOffset * params.mRectSpace * 2);
            mLeftTopCenterY = height / 2 - params.mRectSpace / 2 + mOffset * params.mRectSpace * 2;
        } else {
            mLeftTopCenterX = (float) (width / 2 - params.mRectSpace / 2 + (1 - mOffset) * params.mRectSpace * 2);
            mLeftTopCenterY = (float) (height / 2 - params.mRectSpace / 2 + (1 - mOffset) * params.mRectSpace * 2);
        }
        canvas.drawCircle(mLeftTopCenterX, mLeftTopCenterY, params.mCircleRadius, mLeftTopPaint);
    }

    private void drawLeftButtomCircle(float width, float height, Canvas canvas) {
        float mLeftBottomCenterX;
        float mLeftBottomCenterY;
        if (mOffset <= valueZeroPointFive) {
            mLeftBottomCenterX = width / 2 - params.mRectSpace / 2 + mOffset * params.mRectSpace * 2;
            mLeftBottomCenterY = height / 2 + params.mRectSpace / 2 - mOffset * params.mRectSpace * 2;
        } else {
            mLeftBottomCenterX = (float) (width / 2 - params.mRectSpace / 2 + (1 - mOffset) * params.mRectSpace * 2);
            mLeftBottomCenterY = (float) (height / 2 + params.mRectSpace / 2 - (1 - mOffset) * params.mRectSpace * 2);
        }
        canvas.drawCircle(mLeftBottomCenterX, mLeftBottomCenterY, params.mCircleRadius, mLeftBottomPaint);
    }

    private void drawRightTopCircle(float width, float height, Canvas canvas) {
        float mRightTopCenterX;
        float mRightTopCenterY;
        if (mOffset <= valueZeroPointFive) {
            mRightTopCenterX = width / 2 + params.mRectSpace / 2 - mOffset * params.mRectSpace * 2;
            mRightTopCenterY = height / 2 - params.mRectSpace / 2 + mOffset * params.mRectSpace * 2;
        } else {
            mRightTopCenterX = (float) (width / 2 + params.mRectSpace / 2 - (1 - mOffset) * params.mRectSpace * 2);
            mRightTopCenterY = (float) (height / 2 - params.mRectSpace / 2 + (1 - mOffset) * params.mRectSpace * 2);
        }
        canvas.drawCircle(mRightTopCenterX, mRightTopCenterY, params.mCircleRadius, mRightTopPaint);
    }

    private void drawRightButtomCircle(float width, float height, Canvas canvas) {
        float mRightBottomCenterX;
        float mRightBottomCenterY;
        if (mOffset <= valueZeroPointFive) {
            mRightBottomCenterX = width / 2 + params.mRectSpace / 2 - mOffset * params.mRectSpace * 2;
            mRightBottomCenterY = height / 2 + params.mRectSpace / 2 - mOffset * params.mRectSpace * 2;
        } else {
            mRightBottomCenterX = (float) (width / 2 + params.mRectSpace / 2 - (1 - mOffset) * params.mRectSpace * 2);
            mRightBottomCenterY = (float) (height / 2 + params.mRectSpace / 2 - (1 - mOffset) * params.mRectSpace * 2);
        }
        canvas.drawCircle(mRightBottomCenterX, mRightBottomCenterY, params.mCircleRadius, mRightBottomPaint);
    }

    /**
     * 构建者
     */
    public static class ChromeFloatingCirclesBuild {
        ChromeFloatingCirclesParams params;
        IComponentCallback call;
        private int valueFour = 4;

        public ChromeFloatingCirclesBuild(IComponentCallback c) {
            call = c;
            params = new ChromeFloatingCirclesParams();
            setDurtion(ChromeFloatingCirclesParams.DEFALUT_DURTION);
        }


        public ChromeFloatingCirclesBuild setDurtion(int dur) {
            params.durtion = dur;
            return this;
        }

        public ChromeFloatingCirclesBuild setColor(String[] color) {
            if (color != null && color.length == valueFour) {
                params.colors = new Color[]{new Color(Color.getIntColor(color[0])),
                        new Color(Color.getIntColor(color[1])),
                        new Color(Color.getIntColor(color[2])),
                        new Color(Color.getIntColor(color[3]))};
            } else {
                //TODO 输出日志 提示
            }
            return this;
        }

        public ChromeFloatingCirclesBuild setRectSpace(int space) {
            params.mRectSpace = space;
            return this;
        }

        public ChromeFloatingCirclesBuild setCircleRadius(int radius) {
            params.mCircleRadius = radius;
            return this;
        }

        public ChromeFloatingCirclesElement build() {
            return new ChromeFloatingCirclesElement(params, call);
        }
    }

    /***
     * 可配置参数类
     */
    public static class ChromeFloatingCirclesParams {
        //绘制圆球的半径
        float mCircleRadius = 30;
        float mRectSpace = 120;
        private static final int DEFALUT_DURTION = 3000;
        Color[] colors = new Color[]{new Color(Color.getIntColor("#C93437")),
                new Color(Color.getIntColor("#375BF1")),
                new Color(Color.getIntColor("#F7D23E")),
                new Color(Color.getIntColor("#34A350"))};

        private int durtion = DEFALUT_DURTION;

    }
}
